#include <stdio.h>
#include <stack>
#include <iostream>

#include "crosslist_base.h"
#include "sys_inner.h"
#include "sys_display.h"
#include "sys_heart.h"
#include "sys_flow.h"

using namespace std;

#define SYSFLOW_INFO(...) fprintf(stdout, "\033[32m[SYSFLOW_INFO] %s(%d): \033[0m", __FUNCTION__, __LINE__),fprintf(stdout, __VA_ARGS__)
#define SYSFLOW_ERR(...) fprintf(stderr, "\033[31m[SYSFLOW_ERR] %s(%d): \033[0m", __FUNCTION__, __LINE__),fprintf(stderr, __VA_ARGS__)

struct SysFlowStruct {
    stack<Scene*> sceneStack; //场景栈
    Scene rootScene; //正在参与绘制的场景

    SysHeartUser *heartUsr = NULL; //场景切换动画心跳
    int32_t frame = 0; //帧倒计时
    SysFlowCutType leaveType = SFCT_NONE;
    SysFlowCutType enterType = SFCT_NONE;
};

static SysFlowStruct *gSysFlow = NULL;

// ----- 外部方法 -----

int32_t SysFlowNext(
    Scene *nextScene,
    int32_t frame,
    SysFlowCutType leaveType,
    SysFlowCutType enterType)
{
    Scene *currentScene = gSysFlow->sceneStack.top();
    gSysFlow->sceneStack.push(nextScene);

    //加载场景
    nextScene->OnBegin();

    //参与绘制
    gSysFlow->rootScene.PushBackChild(nextScene);

    //特效过程
    gSysFlow->frame = frame;
    gSysFlow->leaveType = leaveType;
    gSysFlow->enterType = enterType;

    //移出绘制
    if (currentScene)
        currentScene->Remove();

    //结束当前
    if (currentScene)
        currentScene->OnExit();
    return 0;
}

int32_t SysFlowPrevious(
    int32_t frame,
    SysFlowCutType leaveType,
    SysFlowCutType enterType)
{
    Scene *currentScene = gSysFlow->sceneStack.top();
    gSysFlow->sceneStack.pop();
    Scene *previousScene = gSysFlow->sceneStack.top();

    //加载上一个场景
    if (previousScene)
        previousScene->OnBegin();

    //参与绘制
    if (previousScene)
        gSysFlow->rootScene.PushBackChild(previousScene);
    
    //特效过程
    gSysFlow->frame = frame;
    gSysFlow->leaveType = leaveType;
    gSysFlow->enterType = enterType;

    //移出绘制
    if (currentScene)
        currentScene->Remove();

    //结束当前场景
    if (currentScene)
        currentScene->OnExit();

    //内存回收
    if (currentScene)
        delete currentScene;
    return 0;
}

int32_t SysFlowInsert(
    Scene *insertScene,
    int32_t frame,
    SysFlowCutType enterType)
{
    Scene *currentScene = gSysFlow->sceneStack.top();
    if (!currentScene)
        return -1;

    //加载场景
    insertScene->OnBegin();

    //参与绘制
    //作为当前场景的子场景插入
    currentScene->PushBackChild(insertScene);

    //特效过程
    gSysFlow->frame = frame;
    gSysFlow->leaveType = SFCT_NONE;
    gSysFlow->enterType = enterType;
    return 0;
}

// --------- 内部方法 ----------

static int32_t SysFlowHeartCallback(void* priv, SysHeartType type, int32_t index)
{
    //返回1请求刷屏
    if (gSysFlow->frame > 0)
    {
        gSysFlow->frame -= 1;
        return 1;
    }
    return 0;
}

int32_t SysInner::SysFlowDraw()
{
    if (!gSysFlow)
        return -1;
    //黑色清屏
    SysDisplayClear(0);
    //画场景
    SysDisplay(&gSysFlow->rootScene);
    //使能输出
    SysDisplayRefresh();
    return 0;
}

int32_t SysInner::SysFlowInit()
{
    gSysFlow = new SysFlowStruct();

    //stack栈首不得为空,否则调用top()崩溃
    gSysFlow->sceneStack.empty();
    gSysFlow->sceneStack.push(NULL);

    //注册过场动画心跳
    gSysFlow->heartUsr = SysHeartRegister(NULL, SysFlowHeartCallback, SYS_HERAT_TYPE_FAST);

    return 0;
}

int32_t SysInner::SysFlowDeInit()
{
    //解除场动画心跳
    SysHeartUnRegister(gSysFlow->heartUsr);

    //清空绘制对象
    while (gSysFlow->rootScene.LastChild())
        gSysFlow->rootScene.LastChild()->Remove();

    //释放场景栈
    Scene *scene = gSysFlow->sceneStack.top();
    while (scene)
    {
        gSysFlow->sceneStack.pop();
        delete scene;
        scene = gSysFlow->sceneStack.top();
    }

    delete gSysFlow;
    gSysFlow = NULL;
    return 0;
}
